import java.io.*;
import java.net.*;
import javax.swing.*;
import java.awt.*;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;

public class ChatClient {
    private String serverAddress;
    private int port;
    private String username;
    private PrintWriter out;
    private BufferedReader in;
    private Socket socket;
    private JFrame loginFrame;
    private JFrame chatFrame;
    private JTextArea chatArea;
    private JTextField inputField;
    private DefaultListModel<String> userListModel;

    public ChatClient(String serverAddress, int port) {
        this.serverAddress = serverAddress;
        this.port = port;
        createLoginWindow();
    }

    // 创建登录窗口
    private void createLoginWindow() {
        loginFrame = new JFrame("聊天登录");
        loginFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        loginFrame.setSize(300, 200);
        loginFrame.setLocationRelativeTo(null);

        JPanel panel = new JPanel();
        panel.setLayout(new BoxLayout(panel, BoxLayout.Y_AXIS));

        JLabel userLabel = new JLabel("用户名:");
        JTextField userField = new JTextField(20);

        JLabel passLabel = new JLabel("密码:");
        JPasswordField passField = new JPasswordField(20);

        JButton loginButton = new JButton("登录");
        loginButton.addActionListener(e -> {
            String user = userField.getText().trim();
            String pass = new String(passField.getPassword()).trim();

            if (user.isEmpty() || pass.isEmpty()) {
                JOptionPane.showMessageDialog(loginFrame,
                        "请输入用户名和密码", "输入错误",
                        JOptionPane.WARNING_MESSAGE);
                return;
            }

            if (attemptLogin(user, pass)) {
                username = user;
                loginFrame.dispose();
                createChatWindow();
                startMessageListener();
            } else {
                JOptionPane.showMessageDialog(loginFrame,
                        "用户名或密码无效", "登录失败",
                        JOptionPane.ERROR_MESSAGE);
            }
        });

        panel.add(userLabel);
        panel.add(userField);
        panel.add(passLabel);
        panel.add(passField);
        panel.add(loginButton);

        loginFrame.add(panel);
        loginFrame.setVisible(true);
    }

    // 尝试登录
    private boolean attemptLogin(String username, String password) {
        try {
            socket = new Socket(serverAddress, port);
            out = new PrintWriter(socket.getOutputStream(), true);
            in = new BufferedReader(new InputStreamReader(socket.getInputStream()));

            String response;
            while ((response = in.readLine()) != null) {
                if (response.equals("USERNAME_REQUEST")) {
                    out.println(username);
                } else if (response.equals("PASSWORD_REQUEST")) {
                    out.println(password);
                } else if (response.equals("LOGIN_SUCCESS")) {
                    return true;
                } else if (response.equals("LOGIN_FAILURE")) {
                    socket.close();
                    return false;
                }
            }
        } catch (IOException e) {
            JOptionPane.showMessageDialog(loginFrame,
                    "无法连接到服务器: " + e.getMessage(),
                    "连接错误", JOptionPane.ERROR_MESSAGE);
            e.printStackTrace();
        }
        return false;
    }

    // 创建聊天窗口
    private void createChatWindow() {
        chatFrame = new JFrame("Chat - " + username);
        chatFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        chatFrame.setSize(600, 500);

        // 聊天区域
        chatArea = new JTextArea();
        chatArea.setEditable(false);
        chatArea.setLineWrap(true);
        JScrollPane chatScrollPane = new JScrollPane(chatArea);

        // 用户列表
        userListModel = new DefaultListModel<>();
        JList<String> userList = new JList<>(userListModel);
        JScrollPane userScrollPane = new JScrollPane(userList);
        userScrollPane.setPreferredSize(new Dimension(100, 0));

        // 输入区域
        JPanel inputPanel = new JPanel(new BorderLayout());
        inputField = new JTextField(40);
        JButton sendButton = new JButton("发送");

        sendButton.addActionListener(e -> sendMessage());
        inputField.addActionListener(e -> sendMessage());

        inputPanel.add(inputField, BorderLayout.CENTER);
        inputPanel.add(sendButton, BorderLayout.EAST);

        // 布局
        JSplitPane splitPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT,
                chatScrollPane, userScrollPane);
        splitPane.setDividerLocation(500);

        chatFrame.getContentPane().add(splitPane, BorderLayout.CENTER);
        chatFrame.getContentPane().add(inputPanel, BorderLayout.SOUTH);

        // 窗口关闭处理
        chatFrame.addWindowListener(new WindowAdapter() {
            @Override
            public void windowClosing(WindowEvent e) {
                if (out != null) {
                    out.println("LOGOUT");
                }
                try {
                    if (socket != null && !socket.isClosed()) {
                        socket.close();
                    }
                } catch (IOException ex) {
                    ex.printStackTrace();
                }
            }
        });

        chatFrame.setVisible(true);
        inputField.requestFocus();
    }

    // 发送消息 - 关键修复：确保自己的消息显示在聊天记录中
    private void sendMessage() {
        String message = inputField.getText().trim();
        if (!message.isEmpty() && out != null) {
            // 1. 先发送消息到服务器
            out.println(message);

            // 2. 立即在自己的聊天窗口显示消息（不依赖服务器返回）
            appendToChatArea(username + ": " + message);

            // 3. 清空输入框
            inputField.setText("");
        }
    }

    // 启动消息监听器
    private void startMessageListener() {
        Thread listenerThread = new Thread(() -> {
            try {
                String message;
                while ((message = in.readLine()) != null) {
                    System.out.println("从服务器接收: " + message);

                    if (message.startsWith("USER_LIST:")) {
                        updateUserList(message.substring("USER_LIST:".length()));
                    } else if (message.equals("LOGOUT_ACK")) {
                        break;
                    } else {
                        // 只显示其他人的消息（自己的消息已经在sendMessage中显示）
                        // 检查消息是否不是自己发送的
                        if (!message.startsWith(username + ":")) {
                            appendToChatArea(message);
                        }
                    }
                }
            } catch (IOException e) {
                System.err.println("连接错误: " + e.getMessage());
                appendToChatArea("错误：已断开与服务器的连接");
            } finally {
                SwingUtilities.invokeLater(() -> {
                    if (chatFrame != null && chatFrame.isVisible()) {
                        chatFrame.dispose();
                        JOptionPane.showMessageDialog(null, "与服务器断开连接");
                    }
                    System.exit(0);
                });
            }
        });
        listenerThread.start();
    }

    // 更新用户列表
    private void updateUserList(String userListStr) {
        SwingUtilities.invokeLater(() -> {
            userListModel.clear();
            if (userListStr != null && !userListStr.isEmpty()) {
                String[] users = userListStr.split(",");
                for (String user : users) {
                    if (!user.isEmpty()) {
                        userListModel.addElement(user);
                    }
                }
            }
        });
    }

    // 添加消息到聊天区域
    private void appendToChatArea(String message) {
        SwingUtilities.invokeLater(() -> {
            if (chatArea != null) {
                java.util.Date date = new java.util.Date();
                String timeStamp = new java.text.SimpleDateFormat("HH:mm:ss").format(date);
                chatArea.append("[" + timeStamp + "] " + message + "\n");
                chatArea.setCaretPosition(chatArea.getDocument().getLength());
            }
        });
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(() -> {
            String serverAddress = "localhost";
            int port = 12345;
            new ChatClient(serverAddress, port);
        });
    }
}
